home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
MPW_TOOL
/
TOOLS
/
TOOLS_WI
/
ICON_8
/
ICONX_FO
/
LMISC.C
< prev
next >
Wrap
Text File
|
1990-03-02
|
14KB
|
572 lines
/*
* File: lmisc.c
* Contents: create, keywd, limit, llist
*/
#include "::h:config.h"
#include "::h:rt.h"
#include "rproto.h"
#include "::h:keyword.h"
#include "::h:version.h"
#ifdef PreProcess
/* include(../M4/lib.m4) /* */
/* */
#endif /* PreProcess */
/*
* create - return an entry block for a co-expression.
*/
OpBlock(create,1,"create",0)
Ocreate(entryp, cargp)
word *entryp;
register dptr cargp;
{
#ifdef Coexpr
register struct b_coexpr *sblkp;
register struct b_refresh *rblkp;
register dptr dp, ndp, dsp;
register word *newsp;
int na, nl, i;
struct b_proc *cproc;
/*
* Get a new co-expression stack and initialize.
*/
if ((sblkp = alccoexp()) == NULL)
RunErr(0, NULL);
/*
* Icon stack starts at word after co-expression stack block. C stack
* starts at end of stack region on machines with down-growing C stacks
* and somewhere in the middle of the region.
*
* The C stack is aligned on a doubleword boundary. For upgrowing
* stacks, the C stack starts in the middle of the stack portion
* of the static block. For downgrowing stacks, the C stack starts
* at the end of the static block.
*/
newsp = (word *)((char *)sblkp + sizeof(struct b_coexpr));
#ifdef UpStack
sblkp->cstate[0] =
((word)((char *)sblkp + (stksize - sizeof(*sblkp))/2)
&~(WordSize*StackAlign-1));
#else /* UpStack */
sblkp->cstate[0] =
((word)((char *)sblkp + stksize - WordSize)&~(WordSize*StackAlign-1));
#endif /* UpStack */
sblkp->es_argp = (dptr )newsp;
/*
* Calculate number of arguments and number of local variables.
* na is nargs + 1 to include Arg0.
*/
na = pfp->pf_nargs + 1;
cproc = (struct b_proc *)BlkLoc(argp[0]);
nl = (int)cproc->ndynam;
/*
* Get a refresh block for the new co-expression.
*/
if (blkreq((word)sizeof(struct b_refresh) +
(na + nl) * sizeof(struct descrip)) == Error)
RunErr(0, NULL);
rblkp = alcrefresh(entryp, na, nl);
sblkp->freshblk.dword = D_Refresh;
BlkLoc(sblkp->freshblk) = (union block *) rblkp;
/*
* Copy current procedure frame marker into refresh block.
*/
rblkp->pfmkr = *pfp;
rblkp->pfmkr.pf_pfp = 0;
/*
* Copy arguments into refresh block and onto new stack.
*/
dp = &argp[0];
ndp = &rblkp->elems[0];
dsp = (dptr)newsp;
for (i = 1; i <= na; i++) {
*dsp++ = *dp;
*ndp++ = *dp++;
}
/*
* Copy procedure frame to new stack and point dsp to word after frame.
*/
*((struct pf_marker *)dsp) = *pfp;
sblkp->es_pfp = (struct pf_marker *)dsp;
sblkp->es_pfp->pf_pfp = 0;
dsp = (dptr)((word *)dsp + Vwsizeof(*pfp));
sblkp->es_ipc.opnd = entryp;
sblkp->es_gfp = 0;
sblkp->es_efp = 0;
sblkp->es_ilevel = 0;
sblkp->tvalloc = NULL;
/*
* Copy locals to new stack and refresh block.
*/
dp = &(pfp->pf_locals)[0];
for (i = 1; i <= nl; i++) {
*dsp++ = *dp;
*ndp++ = *dp++;
}
/*
* Push two null descriptors on the stack.
*/
*dsp++ = nulldesc;
*dsp++ = nulldesc;
sblkp->es_sp = (word *)dsp - 1;
/*
* Return the new co-expression.
*/
Arg0.dword = D_Coexpr;
BlkLoc(Arg0) = (union block *) sblkp;
Return;
#else /* Coexpr */
RunErr(-401, NULL);
#endif /* Coexpr */
}
/*
* keywd - process keyword.
*/
char *feattab[] = {
#if AMIGA
"Amiga",
#endif /* AMIGA */
#if ATARI_ST
"Atari ST",
#endif /* ATARI_ST */
#if HIGHC_386
"MS-DOS/386",
#endif /* HIGHC_386 */
#if MACINTOSH
"Macintosh",
#endif /* MACINTOSH */
#if MSDOS
"MS-DOS",
#endif /* MSDOS */
#if MVS
"MVS",
#endif /* MVS */
#if OS2
"OS/2",
#endif /* OS2 */
#if PORT
"PORT",
#endif /* PORT */
#if UNIX
"UNIX",
#endif /* VM */
#if VMS
"VMS",
#endif /* VMS */
#if !EBCDIC
"ASCII",
#else /* EBCDIC */
"EBCDIC",
#endif /* EBCDIC */
#ifdef IconCalling
"calling to Icon",
#endif /* IconCalling */
#ifdef Coexpr
"co-expressions",
#endif /* Coexpr */
#ifdef Header
"direct execution",
#endif /* Header */
#ifdef EnvVars
"environment variables",
#endif /* EnvVars */
#ifdef TraceBack
"error trace back",
#endif /* TraceBack */
#ifdef EvalTrace
"evaluation tracing",
#endif /* EvalTrace */
#ifdef ExecImages
"executable images",
#endif /* ExecImages */
#ifndef FixedRegions
"expandable regions",
#endif /* FixedRegions */
#ifdef ExternalFunctions
"external functions",
#endif /* ExternalFunctions */
#ifdef FixedRegions
"fixed regions",
#endif /* FixedRegions */
#ifdef KeyBoardFncs
"keyboard functions",
#endif /* KeyBoardFncs */
#ifdef LargeInts
"large integers",
#endif /* LargeInts */
#ifdef MathFncs
"math functions",
#endif /* MathFncs */
#ifdef MemMon
"memory monitoring",
#endif /* MEMMON */
#ifdef Pipes
"pipes",
#endif /* Pipes */
#ifdef StrInvoke
"string invocation",
#endif /* StrInvoke */
#ifdef SystemFnc
"system function",
#endif /* SystemFnc */
#ifdef DosFncs
"MS-DOS extensions",
#endif /* DosFncs */
""
};
LibDcl(keywd,0,"&keywd")
{
register int hour;
register word i;
register char *merid;
char **p;
char sbuf[MaxCvtLen];
extern word coll_stat, coll_str, coll_blk, coll_tot;
long runtim;
struct cal_time ct;
#if MACINTOSH && MPW
/* #pragma unused(nargs) */
#endif /* MACINTOSH && MPW */
/*
* This is just plug and chug code. For whatever keyword is desired,
* the appropriate value is dug out of the system and made into
* a suitable Icon value.
*
* A few special cases are worth noting:
* &pos, &random, &trace - built-in trapped variables are returned
*/
switch ((int)IntVal(Arg0)) {
case K_ASCII:
Arg0.dword = D_Cset;
BlkLoc(Arg0) = (union block *) &k_ascii;
break;
case K_CLOCK:
if (strreq((word)8) == Error)
RunErr(0, NULL);
getitime(&ct);
sprintf(sbuf,"%02d:%02d:%02d", ct.hour, ct.minute, ct.second);
StrLen(Arg0) = 8;
StrLoc(Arg0) = alcstr(sbuf,(word)8);
break;
case K_COLLECTIONS:
MakeInt(coll_tot, &Arg0);
Suspend;
MakeInt(coll_stat, &Arg0);
Suspend;
MakeInt(coll_str, &Arg0);
Suspend;
MakeInt(coll_blk, &Arg0);
Return;
case K_CSET:
Arg0.dword = D_Cset;
BlkLoc(Arg0) = (union block *) &k_cset;
break;
case K_CURRENT:
Arg0 = k_current;
break;
case K_DATE:
if (strreq((word)10) == Error)
RunErr(0, NULL);
getitime(&ct);
sprintf(sbuf, "%04d/%02d/%02d", ct.year, ct.month_no, ct.mday);
StrLen(Arg0) = 10;
StrLoc(Arg0) = alcstr(sbuf,(word)10);
break;
case K_DATELINE:
getitime(&ct);
if ((hour = ct.hour) >= 12) {
merid = "pm";
if (hour > 12)
hour -= 12;
}
else {
merid = "am";
if (hour < 1)
hour += 12;
}
sprintf(sbuf, "%s, %s %d, %d %d:%02d %s", ct.wday, ct.month_nm,
ct.mday, ct.year, hour, ct.minute, merid);
if (strreq(i = strlen(sbuf)) == Error)
RunErr(0, NULL);
StrLen(Arg0) = i;
StrLoc(Arg0) = alcstr(sbuf, i);
break;
case K_DIGITS:
Arg0.dword = D_Cset;
BlkLoc(Arg0) = (union block *)&k_digits;
break;
case K_ERROR:
Arg0.dword = D_Tvkywd;
BlkLoc(Arg0) = (union block *)&tvky_err;
break;
case K_ERRORNUMBER:
if (k_errornumber == 0)
Fail;
MakeInt((k_errornumber > 0 ? k_errornumber : -k_errornumber), &Arg0);
break;
case K_ERRORTEXT:
if (k_errornumber == 0)
Fail;
StrLoc(Arg0) = k_errortext;
StrLen(Arg0) = strlen(k_errortext);
break;
case K_ERRORVALUE:
if (k_errornumber <= 0)
Fail;
Arg0 = k_errorvalue;
break;
case K_ERROUT:
Arg0.dword = D_File;
BlkLoc(Arg0) = (union block *)&k_errout;
break;
case K_FEATURES:
p = feattab;
for(;;) {
StrLen(Arg0) = strlen(*p);
if (StrLen(Arg0) == 0)
Fail;
StrLoc(Arg0) = *p;
Suspend;
p++;
}
case K_FILE:
StrLoc(Arg0) = findfile(ipc.opnd);
StrLen(Arg0) = strlen(StrLoc(Arg0));
break;
case K_HOST:
iconhost(sbuf);
if (strreq(i = strlen(sbuf)) == Error)
RunErr(0, NULL);
StrLen(Arg0) = i;
StrLoc(Arg0) = alcstr(sbuf, i);
break;
case K_INPUT:
Arg0.dword = D_File;
BlkLoc(Arg0) = (union block *)&k_input;
break;
case K_LCASE:
Arg0.dword = D_Cset;
BlkLoc(Arg0) = (union block *)&k_lcase;
break;
case K_LETTERS:
Arg0.dword = D_Cset;
BlkLoc(Arg0) = (union block *)&k_letters;
break;
case K_LEVEL:
MakeInt(k_level, &Arg0);
break;
case K_LINE:
MakeInt(findline(ipc.opnd), &Arg0);
break;
case K_MAIN:
Arg0 = k_main;
break;
case K_OUTPUT:
Arg0.dword = D_File;
BlkLoc(Arg0) = (union block *)&k_output;
break;
case K_POS:
Arg0.dword = D_Tvkywd;
BlkLoc(Arg0) = (union block *) &tvky_pos;
break;
case K_RANDOM:
Arg0.dword = D_Tvkywd;
BlkLoc(Arg0) = (union block *) &tvky_ran;
break;
case K_REGIONS:
#ifdef FixedRegions
Arg0 = zerodesc;
#else /* FixedRegions */
MakeInt(DiffPtrs(statend,statbase) - mstksize, &Arg0);
#endif /* FixedRegions */
Suspend;
MakeInt(DiffPtrs(strend,strbase), &Arg0);
Suspend;
MakeInt(DiffPtrs(blkend,blkbase), &Arg0);
Return;
case K_SOURCE:
#ifndef Coexpr
Arg(0) = k_main;
#else /* Coexpr */
Arg0.dword = D_Coexpr;
BlkLoc(Arg0) =
(union block *)topact((struct b_coexpr *)BlkLoc(k_current));
#endif /* Coexpr */
break;
case K_STORAGE:
#ifdef FixedRegions
Arg0 = zerodesc;
#else /* FixedRegions */
MakeInt(DiffPtrs(statfree,statbase) - mstksize, &Arg0);
#endif /* FixedRegions */
Suspend;
MakeInt(DiffPtrs(strfree,strbase), &Arg0);
Suspend;
MakeInt(DiffPtrs(blkfree,blkbase), &Arg0);
Return;
case K_SUBJECT:
Arg0.dword = D_Tvkywd;
BlkLoc(Arg0) = (union block *) &tvky_sub;
break;
case K_TIME:
runtim = millisec();
MakeInt(runtim, &Arg0);
break;
case K_TRACE:
Arg0.dword = D_Tvkywd;
BlkLoc(Arg0) = (union block *)&tvky_trc;
break;
case K_UCASE:
Arg0.dword = D_Cset;
BlkLoc(Arg0) = (union block *)&k_ucase;
break;
case K_VERSION:
if (strreq(i = strlen(Version)) == Error)
RunErr(0, NULL);
StrLen(Arg0) = i;
StrLoc(Arg0) = Version;
break;
default:
syserr("keyword: unknown keyword type.");
}
Return;
}
/*
* limit - explicit limitation initialization.
*/
#ifdef WATERLOO_C_V3_0
struct b_iproc Blimit = {
T_Proc,
Vsizeof(struct b_proc),
Olimit,
2,
-1,
0,
0,
{sizeof(BackSlash)-1,BackSlash}}; Olimit(nargs,cargp,sptr) register dptr cargp;
#else /* WATERLOO_C_V3_0 */
LibDcl(limit,2,BackSlash)
#endif /* WATERLOO_C_V3_0 */
{
#if MACINTOSH
#if MPW
/* #pragma unused(nargs) */
#endif /* MPW */
#endif /* MACINTOSH */
/*
* The limit is both passed and returned in Arg0. The limit must
* be an integer. If the limit is 0, the expression being evaluated
* fails. If the limit is < 0, it is an error. Note that the
* result produced by limit is ultimately picked up by the lsusp
* function.
*/
if (DeRef(Arg0) == Error)
RunErr(0, NULL);
switch (cvint(&Arg0)) {
case T_Integer:
break;
default:
RunErr(101, &Arg0);
}
if (IntVal(Arg0) < 0)
RunErr(205, &Arg0);
if (IntVal(Arg0) == 0)
Fail;
Return;
}
/*
* [ ... ] - create an explicitly specified list.
*/
LibDcl(llist,-1,"[...]")
{
register word i;
register struct b_list *hp;
register struct b_lelem *bp;
word nslots;
nslots = nargs;
if (nslots == 0)
nslots = MinListSlots;
if (blkreq((word)sizeof(struct b_list) + sizeof(struct b_lelem) +
nslots * sizeof(struct descrip)) == Error)
RunErr(0, NULL);
/*
* Allocate the list and a list block.
*/
hp = alclist((word)nargs);
bp = alclstb(nslots, (word)0, (word)nargs);
/*
* Make the list block just allocated into the first and last blocks
* for the list.
*/
hp->listhead = hp->listtail = (union block *)bp;
/*
* Dereference each argument in turn and assign it to a list element.
*/
for (i = 1; i <= nargs; i++) {
if (DeRef(Arg(i)) == Error)
RunErr(0, NULL);
bp->lslots[i-1] = Arg(i);
}
/*
* Point Arg0 at the new list and return it.
*/
ArgType(0) = D_List;
Arg(0).vword.bptr = (union block *)hp;
Return;
}